package com.lai.gulimall.member.service.impl;

import cn.hutool.core.date.DateUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.lai.common.constant.AuthServerConstant;
import com.lai.common.constant.MemberConstant;
import com.lai.common.exception.RRException;
import com.lai.common.to.SocialUserDto;
import com.lai.gulimall.member.dto.MemberLoginDto;
import com.lai.gulimall.member.dto.MemberRegisterDto;
import com.lai.gulimall.member.entity.MemberLevelEntity;
import com.lai.gulimall.member.service.MemberLevelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lai.common.utils.PageUtils;
import com.lai.common.utils.Query;

import com.lai.gulimall.member.dao.MemberDao;
import com.lai.gulimall.member.entity.MemberEntity;
import com.lai.gulimall.member.service.MemberService;
import org.springframework.util.StringUtils;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    MemberLevelService memberLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(MemberRegisterDto memberRegisterDto) {
        MemberEntity memberEntity = new MemberEntity();

        //检查用户名和手机号是否在数据库中存在
        checkPhoneUnique(memberRegisterDto.getPhoneNumbers());
        checkUsernameUnique(memberRegisterDto.getUsername());

        //查出会员默认等级
        MemberLevelEntity memberLevelEntity = memberLevelService.getOne(new QueryWrapper<MemberLevelEntity>().eq("default_status", 1));

        memberEntity.setLevelId(memberLevelEntity.getId());
        memberEntity.setMobile(memberRegisterDto.getPhoneNumbers());
        memberEntity.setUsername(memberRegisterDto.getUsername());
        memberEntity.setNickname(memberRegisterDto.getUsername());

        //密码进行加密存储
        /**
         * 当时看到使用 BCryptPasswordEncoder 时，同样的密码可以生成不同的 密文 而且还可以通过 matches 方法进行匹配验证，觉得很神奇。
         * 后来经过调试发现，密文中本身包含了很多信息，包括 salt 和 使用 salt 加密后的 hash。因为每次的 salt 不同，因此每次的 hash 也不同。
         * 这样就可以使得相同的 明文 生成不同的 密文，而密文中包含 salt 和 hash，因此验证过程和生成过程也是相同的
         */
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode(memberRegisterDto.getPassword());
        memberEntity.setPassword(password);

        baseMapper.insert(memberEntity);
    }

    @Override
    public void checkUsernameUnique(String username) {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username));
        if (count > 0) {
            throw new RRException("用户名已存在");
        }

    }

    @Override
    public void checkPhoneUnique(String phone) {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (count > 0) {
            throw new RRException("手机号已存在");
        }

    }

    @Override
    public MemberEntity login(MemberLoginDto memberLoginDto) {
        //根据 account 查询这个用户是否存在
        MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", memberLoginDto.getAccount())
                .or().eq("mobile", memberLoginDto.getAccount())
                .or().eq("email", memberLoginDto.getAccount()));

        if (!StringUtils.isEmpty(memberEntity)) {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            boolean matches = bCryptPasswordEncoder.matches(memberLoginDto.getPassword(), memberEntity.getPassword());
            return matches ? memberEntity : null;
        } else {
            //登录失败   没有查询到这个用户
            return null;
        }
    }

    @Override
    public MemberEntity oauth2Login(SocialUserDto socialUserDto) {
        Gson gson = new Gson();
        MemberLevelEntity memberLevelEntity = memberLevelService.getOne(new QueryWrapper<MemberLevelEntity>().eq("default_status", 1));
        //微博用户登录
        if (!StringUtils.isEmpty(socialUserDto.getSocialId()) && socialUserDto.getSocialType() == AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_WEIBO.getCode()) {
            //判断此社交用户是否以前登录过  根据社交用户唯一id（social_id）和用户来源 （source_type）判断
            MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_id", socialUserDto.getSocialId()).and(memberEntityQueryWrapper -> {
                memberEntityQueryWrapper.eq("source_type", AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_WEIBO.getCode());
            }));
            if (memberEntity != null) {//不为空   表示该社交用户不是第一次登录
                memberEntity.setUsername(socialUserDto.getUsername());
                memberEntity.setNickname(socialUserDto.getNickname());
                memberEntity.setCity(socialUserDto.getCity());
                memberEntity.setHeader(socialUserDto.getHeader());
                memberEntity.setSign(socialUserDto.getSign());
                memberEntity.setGender(socialUserDto.getGender());
                memberEntity.setSourceType(AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_WEIBO.getCode());
                //执行修改操作  修改刚才查询出来的实体 memberEntity
                int update = baseMapper.updateById(memberEntity);
                if (update > 0) {
                    return memberEntity;
                }
            } else {//为空   表示该社交用户是第一次登录
                MemberEntity entity = new MemberEntity();
                entity.setSocialId(socialUserDto.getSocialId());
                entity.setUsername(socialUserDto.getUsername());
                entity.setNickname(socialUserDto.getNickname());
                entity.setCity(socialUserDto.getCity());
                entity.setHeader(socialUserDto.getHeader());
                entity.setSign(socialUserDto.getSign());
                entity.setGender(socialUserDto.getGender());
                entity.setSourceType(AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_WEIBO.getCode());
                entity.setCreateTime(DateUtil.date());
                entity.setLevelId(memberLevelEntity.getId());
                entity.setStatus(MemberConstant.MemberEnum.IS_ENABLED.getCode());
                //执行修改操作  修改刚才查询出来的实体 memberEntity
                //为该社交用户插入一条数据
                int insert = baseMapper.insert(entity);
                if (insert > 0) {
                    return entity;
                } else {
                    return null;
                }
            }
            //GITEE用户登录
        } else if (!StringUtils.isEmpty(socialUserDto.getSocialId()) && socialUserDto.getSocialType() == AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_GITEE.getCode()) {
            //判断此社交用户是否以前登录过  根据社交用户唯一id（social_id）和用户来源 （source_type）判断
            MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_id", socialUserDto.getSocialId()).and(memberEntityQueryWrapper -> {
                memberEntityQueryWrapper.eq("source_type", AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_GITEE.getCode());
            }));
            if (memberEntity != null) {//不为空   表示该社交用户不是第一次登录
                memberEntity.setUsername(socialUserDto.getUsername());
                memberEntity.setNickname(socialUserDto.getNickname());
                memberEntity.setEmail(socialUserDto.getEmail());
                memberEntity.setHeader(socialUserDto.getHeader());
                memberEntity.setSign(socialUserDto.getSign());
                memberEntity.setStatus(MemberConstant.MemberEnum.IS_ENABLED.getCode());
                //执行修改操作  修改刚才查询出来的实体 memberEntity
                int update = baseMapper.updateById(memberEntity);
                if (update > 0) {
                    return memberEntity;
                } else {
                    return null;
                }
            } else {//为空   表示该社交用户是第一次登录
                MemberEntity entity = new MemberEntity();
                entity.setSocialId(socialUserDto.getSocialId());
                entity.setUsername(socialUserDto.getUsername());
                entity.setNickname(socialUserDto.getNickname());
                entity.setEmail(socialUserDto.getEmail());
                entity.setHeader(socialUserDto.getHeader());
                entity.setSign(socialUserDto.getSign());
                entity.setLevelId(memberLevelEntity.getId());
                entity.setSourceType(AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_GITEE.getCode());
                entity.setStatus(MemberConstant.MemberEnum.IS_ENABLED.getCode());
                entity.setCreateTime(DateUtil.date());
                //为该社交用户插入一条数据
                int insert = baseMapper.insert(entity);
                if (insert > 0) {
                    return entity;
                } else {
                    return null;
                }
            }

            //GITHUB用户登录
        } else if (!StringUtils.isEmpty(socialUserDto.getSocialId()) && socialUserDto.getSocialType() == AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_GITHUB.getCode()) {
            //判断此社交用户是否以前登录过  根据社交用户唯一id（social_id）和用户来源 （source_type）判断
            MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_id", socialUserDto.getSocialId()).and(memberEntityQueryWrapper -> {
                memberEntityQueryWrapper.eq("source_type", AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_GITHUB.getCode());
            }));

            if (memberEntity != null) {//不为空   表示该社交用户不是第一次登录
                memberEntity.setUsername(socialUserDto.getUsername());
                memberEntity.setNickname(socialUserDto.getNickname());
                memberEntity.setEmail(socialUserDto.getEmail());
                memberEntity.setHeader(socialUserDto.getHeader());
                memberEntity.setSign(socialUserDto.getSign());
                memberEntity.setCity(socialUserDto.getCity());
                memberEntity.setStatus(MemberConstant.MemberEnum.IS_ENABLED.getCode());
                memberEntity.setCreateTime(DateUtil.date());
                //执行修改操作  修改刚才查询出来的实体 memberEntity
                int update = baseMapper.updateById(memberEntity);
                if (update > 0) {
                    return memberEntity;
                } else {
                    return null;
                }
            } else {//为空   表示该社交用户是第一次登录
                MemberEntity entity = new MemberEntity();
                entity.setSocialId(socialUserDto.getSocialId());
                entity.setUsername(socialUserDto.getUsername());
                entity.setNickname(socialUserDto.getNickname());
                entity.setEmail(socialUserDto.getEmail());
                entity.setHeader(socialUserDto.getHeader());
                entity.setSign(socialUserDto.getSign());
                entity.setCity(socialUserDto.getCity());
                entity.setLevelId(memberLevelEntity.getId());
                entity.setSourceType(AuthServerConstant.Oauth2Enum.Oauth2_PLATFORM_GITHUB.getCode());
                entity.setStatus(MemberConstant.MemberEnum.IS_ENABLED.getCode());
                entity.setCreateTime(DateUtil.date());
                //为该社交用户插入一条数据
                int insert = baseMapper.insert(entity);
                if (insert > 0) {
                    return entity;
                } else {
                    return null;
                }
            }
        }
        return null;
    }

}